import { Request, Response } from 'express';
import loginInfoService from '@/services/system/loginInfo.service';
import ApiResponse from '@/utils/api/api-response.util';
import { Log, BusinessType } from '@/decorators/Log';
import ExcelUtil from '@/utils/excel/excel.util';
import { getLogger } from '@/utils/logger';
import passwordService from '@/services/system/password.service';
import AsyncManager from '@/utils/async/AsyncManager';
import AsyncFactory from '@/utils/async/AsyncFactory';
import { AuthRequest } from '@/types';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("logininfo-controller");
const logger = getLogger("logininfo-controller", {
	console: false,
});

/**
 * 系统访问记录
 */
class LoginInfoController {
  /**
   * 查询系统登录日志列表
   * @param req 请求对象
   * @param res 响应对象
   */
  public async list(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取登录日志列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      // 构建查询条件
      const loginInfo = {
        ipaddr: req.query.ipaddr as string,
        userName: req.query.userName as string, 
        status: req.query.status as string,
        params: {
          beginTime: req.query.beginTime as string,
          endTime: req.query.endTime as string
        },
        orderByColumn: req.query.orderByColumn as string,
        isAsc: req.query.isAsc as string
      };
      
      // 查询登录日志列表
      const list = await loginInfoService.selectLoginInfoList(loginInfo);
      
      // 返回分页数据
      const page = parseInt(req.query.pageNum as string) || 1;
      const pageSize = parseInt(req.query.pageSize as string) || 10;
      
      // 结果日志
      logger.info("获取登录日志列表成功", {
        response: {
          count: list.length,
          page,
          pageSize,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.page(res, list, list.length, page, pageSize);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取登录日志列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '获取登录日志列表失败');
      }
    }
  }
  
  /**
   * 导出系统登录日志
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '登录日志', businessType: BusinessType.EXPORT })
  public async export(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("导出登录日志请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      // 构建查询条件
      const loginInfo = {
        ipaddr: req.query.ipaddr as string,
        userName: req.query.userName as string, 
        status: req.query.status as string,
        params: {
          beginTime: req.query.beginTime as string,
          endTime: req.query.endTime as string
        }
      };
      
      // 查询所有登录日志
      const list = await loginInfoService.selectLoginInfoList(loginInfo);
      
      // 定义导出字段配置
      const fields = [
        { header: '访问编号', key: 'infoId', width: 10 },
        { header: '用户名称', key: 'userName', width: 20 },
        { header: '登录地址', key: 'ipaddr', width: 20 },
        { header: '登录地点', key: 'loginLocation', width: 20 },
        { header: '浏览器', key: 'browser', width: 20 },
        { header: '操作系统', key: 'os', width: 15 },
        { header: '登录状态', key: 'status', width: 10, formatter: (value: string) => value === '0' ? '成功' : '失败' },
        { header: '操作信息', key: 'msg', width: 20 },
        { header: '登录日期', key: 'loginTime', width: 20, type: 'datetime' }
      ];
      
      // 导出Excel
      await ExcelUtil.exportToResponse(
        res,
        list,
        fields,
        `logininfor_${Date.now()}`,
        '登录日志'
      );
      
      // 结果日志
      logger.info("导出登录日志成功", {
        response: {
          count: list.length,
        },
        operator: req.user?.userName || 'unknown',
      });
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`导出登录日志失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '导出登录日志失败', 500);
      }
    }
  }
  
  /**
   * 删除系统登录日志
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '登录日志', businessType: BusinessType.DELETE })
  public async remove(req: AuthRequest, res: Response) {
    try {
      // 获取要删除的日志ID数组
      const infoIds = req.params.infoIds.split(',').map(id => parseInt(id));
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("删除登录日志请求", {
        params: req.params,
        infoIds,
        operator,
      });
      
      // 执行删除操作
      const result = await loginInfoService.deleteLoginInfoByIds(infoIds);
      
      // 结果日志
      logger.info("删除登录日志成功", {
        response: {
          infoIds,
          result,
        },
        operator,
      });
      
      // 返回结果
      ApiResponse.success(res, result, '删除成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`删除登录日志失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '删除登录日志失败');
      }
    }
  }
  
  /**
   * 清空登录日志
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '登录日志', businessType: BusinessType.CLEAN })
  public async clean(req: AuthRequest, res: Response) {
    try {
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("清空登录日志请求", {
        operator,
      });
      
      // 执行清空操作
      await loginInfoService.cleanLoginInfo();
      
      // 结果日志
      logger.info("清空登录日志成功", {
        operator,
      });
      
      // 返回结果
      ApiResponse.success(res, null, '清空成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`清空登录日志失败: ${error instanceof Error ? error.message : String(error)}`, {
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '清空登录日志失败');
      }
    }
  }
  
  /**
   * 解锁用户登录状态
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '账户解锁', businessType: BusinessType.OTHER })
  public async unlock(req: AuthRequest, res: Response) {
    try {
      const userName = req.params.userName;
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("解锁用户登录状态请求", {
        params: req.params,
        userName,
        operator,
      });
      
      if (!userName) {
        consoleLogger.warn('解锁用户登录状态 - 用户名为空', { operator });
        ApiResponse.error(res, '用户名不能为空', 400);
        return;
      }
      
      // 清除密码重试缓存
      await passwordService.clearLoginRetryCount(userName);
      
      // 记录解锁日志
      AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, 'Success', '账户解锁'));
      
      // 结果日志
      logger.info("解锁用户登录状态成功", {
        response: {
          userName,
        },
        operator,
      });
      
      ApiResponse.success(res, null, `用户${userName}解锁成功`);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`解锁用户登录状态失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '解锁用户登录状态失败');
      }
    }
  }
  
  /**
   * 登录统计信息
   * @param req 请求对象
   * @param res 响应对象
   */
  public async statistic(req: Request, res: Response) {
    try {
      const userName = req.query.userName as string;
      const days = parseInt(req.query.days as string) || 7;
      
      // 请求日志
      consoleLogger.info("获取登录统计信息请求", {
        query: req.query,
        userName,
        days,
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取统计数据
      const statisticData = await loginInfoService.countUserLoginInfo(userName, days);
      
      // 结果日志
      logger.info("获取登录统计信息成功", {
        response: {
          userName,
          days,
          hasData: !!statisticData,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, statisticData);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取登录统计信息失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '获取登录统计信息失败');
      }
    }
  }
}

export default new LoginInfoController(); 